import time
import traceback
from contextlib import ContextDecorator

from colorama import Fore
from tqdm import trange

from .logger import logger

__all__ = 'TryExcept', 'log_print', 'short_rest', 'tip', 'timer'


class Tip(object):
    """在函数前后打印 tip"""

    i = 0
    colors = Fore.CYAN, Fore.GREEN, Fore.RED, Fore.YELLOW, Fore.MAGENTA, Fore.BLUE

    def register(self, message: str, color=None):
        self.i += 1
        color = color if color else self.colors[self.i % len(self.colors)]

        def outer(func):
            def inner(*args, **kwargs):
                _tip = f'-*-*-*-*-*-*-*-*-*-*-*-* {message} -*-*-*-*-*-*-*-*-*-*-*-*-'
                log_print(_tip, log_level='info', color=color)
                res = func(*args, **kwargs)
                log_print(_tip + '\n', log_level='info', color=color)
                return res

            return inner

        return outer


class TryExcept(ContextDecorator):
    """捕获异常"""

    def __init__(self, not_raise=True, level: str = 'error'):
        self.not_raise = not_raise
        self.level = level

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            traces = ''.join(traceback.format_tb(exc_tb))
            message = f'Error occurred!!!\nTraceback:\n{traces}{exc_type.__name__}:{exc_val}'
            log_print(message, self.level)

        return self.not_raise


def log_print(message: str, log_level='info', color=''):
    """打印消息至终端和输出日志至文件"""

    match log_level.lower():
        case 'error':
            logger.error(message)
        case 'warning' | 'warn':
            logger.warning(message)
        case 'info':
            logger.info(message)
        case 'debug':
            logger.debug(message)
        case _:
            logger.warning(message)
    print(color + message)


def short_rest(desc='', num=100, time_interval=0.02):
    """打印进度条"""

    for _ in trange(num, desc=desc):
        time.sleep(time_interval)


def timer(time_interval=14400):
    """自定义定时器,若时时间间隔为time_interval,则返回True"""

    record_t = time.time()
    first = True

    def inner() -> bool:
        nonlocal record_t
        nonlocal first

        # 若第一次定时，则直接返回True
        if first is True:
            first = False
            return True

        now_t = time.time()
        if now_t - record_t >= time_interval:
            record_t = now_t
            return True
        return False

    return inner


tip = Tip()
